package lzupdater.utils;

import java.util.Random;

//LZRosterUpdater, a java client to update LZRoster
//Copyright (C) 2008 Fraskor from Krasus (e-mail: fraskor@gmail.com)
//
//This file is part of LZRosterUpdater.
//
//LZRosterUpdater is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Very simple encryption class.
 * 
 * @author Fraskor
 */
public class Encrypter {

	private Encrypter() {
	};

	public static String encryptString(String password) {
		int salt1;
		int salt2;
		Random random = new Random();
		random.setSeed(password.hashCode());

		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < password.length(); i++) {
			char c = password.charAt(i);

			salt1 = random.nextInt() & 15;
			salt2 = random.nextInt() & 15;

			int b1 = shuffle(salt2, encryptByte(c / 16, salt1));
			int b2 = shuffle(salt1, encryptByte(c & 15, salt2));

			buffer.append((char) (33 + 2 * (b1 / 16)));
			buffer.append((char) (33 + 2 * (b1 & 15)));
			buffer.append((char) (33 + 2 * (b2 / 16)));
			buffer.append((char) (33 + 2 * (b2 & 15)));
		}

		return buffer.toString();
	}

	public static String decryptString(String password) {
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < password.length() - 3; i += 4) {
			int result = 0;
			int b1 = ((password.charAt(i) & 30) * 8 + (password.charAt(i + 1) & 30) / 2);
			int b2 = ((password.charAt(i + 2) & 30) * 8 + (password
					.charAt(i + 3) & 30) / 2);

			int[] dec1 = unshuffle(b1);
			int[] dec2 = unshuffle(b2);

			result += encryptByte(dec2[0], dec1[1]) * 16;
			result += encryptByte(dec1[0], dec2[1]);
			buffer.append((char) result);
		}
		return buffer.toString();
	}

	private static int encryptByte(int b, int salt) {
		return b ^ salt;
	}

	private static int shuffle(int quartet1, int quartet2) {
		return expands(quartet1) + 2 * expands(quartet2);
	}

	private static int[] unshuffle(int value) {
		return new int[] { compress(value), compress(value / 2) };
	}

	private static int expands(int quartet) {
		return (quartet & 1) + (quartet & 2) * 2 + (quartet & 4) * 4
				+ (quartet & 8) * 8;
	}

	private static int compress(int quartet) {
		return (quartet & 1) + (quartet & 4) / 2 + (quartet & 16) / 4
				+ (quartet & 64) / 8;
	}

	public static String getMaskedPassword(String value) {
		StringBuffer buffer = new StringBuffer("*");
		while (buffer.length() < value.length()) {
			buffer.append(buffer);
		}
		return buffer.toString().substring(0, value.length());
	}

}
